<?php
/**
 * 采购单控制器
 */

namespace app\admin\controller;

use app\admin\traits\AdminSettingForm;
use app\admin\traits\SettingContent;
use app\common\model\Brand;
use app\common\model\Check;
use app\common\model\OfferDetail;
use app\common\model\School;
use app\common\model\Send;
use app\common\model\Spec;
use app\common\model\Type;
use app\common\model\User;
use app\common\validate\SendValidate;
use Exception;
use think\db\Query;
use think\Request;
use think\response\Json;

class SendController extends AdminBaseController
{
    use AdminSettingForm;
    use SettingContent;
    /**
     * 列表
     * @param Request $request
     * @param Send $model
     * @return string
     * @throws Exception
     */

    public function index(Request $request, Send $model): string
    {
        $param = $request->param();
        $data  = $model->with(['school', 'user'])->scope('where', $param)
            ->paginate([
                'list_rows' => $this->admin['admin_list_rows'],
                'var_page'  => 'page',
                'query'     => $request->get(),
            ]);
        // 关键词，排序等赋值
        $this->assign($request->get());

        $this->assign([
            'data'        => $data,
            'page'        => $data->render(),
            'total'       => $data->total(),
            'school_list' => School::select(),
            'user_list'   => User::select(),

        ]);
        return $this->fetch();
    }

    /**
     * 添加
     * @param Request $request
     * @param Send $model
     * @param SendValidate $validate
     * @return string|Json
     * @throws Exception
     */
    public function add(Request $request, Send $model, SendValidate $validate)
    {
        if ($request->isPost()) {
            $param = $request->param();
            try {
                $param['detail'] = $this->getSendDetail($param);
            } catch (RuntimeException $exception) {
                return admin_error($exception->getMessage());
            }
            $validate_result = $validate->scene('admin_add')->check($param);
            if (! $validate_result) {
                return admin_error($validate->getError());
            }

            $param['code']  = date('YmdHis') . rand(00000, 99999);
            $param['money'] = array_sum(array_column($param['detail'], 'money'));

            $find_offer = OfferDetail::where('school_id', $param['school_id'])->where('send_time', strtotime($param['send_time']))->findOrEmpty();

            $offer_details = $this->getOfferDetailAdd($param);
            if ($find_offer->isEmpty()) {
                $offer_detail_data = [
                    'name'      => $param['send_time'] . '报价单',
                    'send_id'   => 0,
                    'code'      => date('YmdHis') . rand(00000, 99999),
                    'money'     => array_sum(array_column($offer_details, 'money')),
                    'detail'    => $offer_details,
                    'send_time' => $param['send_time'],
                    'school_id' => $param['school_id'],
                ];
                $offer_detail           = OfferDetail::create($offer_detail_data);
                $offer_detail_result_id = $offer_detail->id;
            } else {

                $offer_details = $this->array_do6($find_offer['detail'], $offer_details);

                foreach ($offer_details as $ok => $ov) {
                    $offer_details[$ok]['money'] = round($ov['price'] * $ov['num'], 2);
                }

                $offer_detail_data = [
                    'name'      => $param['send_time'] . '报价单',
                    'send_id'   => 0,
                    'code'      => date('YmdHis') . rand(00000, 99999),
                    'money'     => array_sum(array_column($offer_details, 'money')),
                    'detail'    => $offer_details,
                    'send_time' => $param['send_time'],
                    'school_id' => $param['school_id'],
                ];
                $offer_detail           = $find_offer->save($offer_detail_data);
                $offer_detail_result_id = $find_offer->id;
            }
            $param['offer_detail_id'] = $offer_detail_result_id;
            $result                   = $model::create($param);

            $url = URL_BACK;
            if (isset($param['_create']) && (int) $param['_create'] === 1) {
                $url = URL_RELOAD;
            }
            return $result ? admin_success('添加成功', [], $url) : admin_error();
        }
        $this->assign([
            'school_list' => School::select(),
            'user_list'   => User::select(),
            'type_list'   => Type::where('parent_id', '<>', 0)->select(),
            'spec_list'   => Spec::select(),
            'brand_list'  => Brand::select(),
            'user_list'   => User::select(),
            'status_list' => Send::STATUS_LIST,
        ]);

        return $this->fetch();
    }
    public function array_do6($array1, $array2)
    {
        $result = [];

// 处理第一个数组
        foreach ($array1 as $item) {
            $type_id          = $item['type_id'];
            $result[$type_id] = $item; // 以 type_id 为键保存第一个数组的内容
        }

// 处理第二个数组
        foreach ($array2 as $item) {
            $type_id = $item['type_id'];

            if (isset($result[$type_id])) {
                // 如果 type_id 存在于第一个数组，则 num 相加，保留第一个数组的 price
                $result[$type_id]['num'] += $item['num'];
            } else {
                // 如果 type_id 不存在于第一个数组，则直接添加到结果数组中
                $result[$type_id] = $item;
            }
        }

// 将结果重新整理成普通数组
        $result = array_values($result);
        return $result;
    }
    /**
     * 修改
     * @param $id
     * @param Request $request
     * @param Send $model
     * @param SendValidate $validate
     * @return string|Json
     * @throws Exception
     */
    public function edit($id, Request $request, Send $model, SendValidate $validate)
    {
        $data = $model->findOrEmpty($id);
        if ($request->isPost()) {
            $param = $request->param();
            try {
                $param['detail'] = $this->getSendDetail($param);
            } catch (RuntimeException $exception) {
                return admin_error($exception->getMessage());
            }
            $check = $validate->scene('admin_edit')->check($param);
            if (! $check) {
                return admin_error($validate->getError());
            }

            $param['money'] = array_sum(array_column($param['detail'], 'money'));
            $result         = $data->save($param);
            $this->offer_detail($id);
            return $result ? admin_success('修改成功', [], URL_BACK) : admin_error('修改失败');
        }

        $this->assign([
            'data'        => $data,
            'school_list' => School::select(),
            'user_list'   => User::select(),
            'type_list'   => Type::where('parent_id', '<>', 0)->select(),
            'spec_list'   => Spec::select(),
            'brand_list'  => Brand::select(),
            'user_list'   => User::select(),
            'status_list' => Send::STATUS_LIST,
        ]);

        return $this->fetch('add');
    }

    /**
     * 删除
     * @param mixed $id
     * @param Send $model
     * @return Json
     */
    public function del($id, Send $model): Json
    {

        $check = $model->inNoDeletionIds($id);
        if (false !== $check) {
            return admin_error('ID为' . $check . '的数据不能被删除');
        }
        $id = Send::where('user_id', $id)->whereDay('create_time')->column('id');
        // print_r($id);
        // exit();
        $list = $model::whereIn('id', $id)->select();
        foreach ($list as $key => $value) {
            $this->offer_details($value['id']);
        }
        $result = $model::destroy(static function ($query) use ($id) {
            /** @var Query $query */
            $query->whereIn('id', $id);
        });

        return $result ? admin_success('删除成功', [], URL_RELOAD) : admin_error('删除失败');
    }

    public function offer_detail($id)
    {
        $data        = Send::find($id);
        $send        = Send::where('school_id', $data['school_id'])->where('send_time', strtotime($data['send_time']))->select()->toArray();
        $detail      = array_column($send, 'detail');
        $twoDimArray = [];

        // 遍历三维数组，将其转换为二维数组
        foreach ($detail as $subArray) {
            foreach ($subArray as $item) {
                $twoDimArray[] = $item;
            }
        }
        $detail = $this->array_dos($twoDimArray);

        $offer_detail = OfferDetail::where('id', $data['offer_detail_id'])->findOrEmpty();
        if (! $offer_detail->isEmpty()) {

            $detail = $this->array_do5($detail, $offer_detail['detail']);

            foreach ($detail as $dk => $dv) {
                $detail[$dk]['money'] = round($dv['price'] * $dv['num'], 2);
            }
            $offer_money = array_sum(array_column($detail, 'money'));

            if (! empty($detail)) {
                $offer_detail->save(['detail' => $detail, 'money' => $offer_money]);
            } else {
                $offer_detail->delete();
            }

        }
    }
    public function offer_details($id)
    {
        $data        = Send::find($id);
        $send        = Send::where('school_id', $data['school_id'])->where('id', '<>', $id)->where('send_time', strtotime($data['send_time']))->select()->toArray();
        $detail      = array_column($send, 'detail');
        $twoDimArray = [];

        // 遍历三维数组，将其转换为二维数组
        foreach ($detail as $subArray) {
            foreach ($subArray as $item) {
                $twoDimArray[] = $item;
            }
        }
        $detail = $this->array_dos($twoDimArray);

        $offer_detail = OfferDetail::where('id', $data['offer_detail_id'])->findOrEmpty();
        if (! $offer_detail->isEmpty()) {

            $detail = $this->array_do5($detail, $offer_detail['detail']);

            foreach ($detail as $dk => $dv) {
                $detail[$dk]['money'] = round($dv['price'] * $dv['num'], 2);
            }
            $offer_money = array_sum(array_column($detail, 'money'));

            if (! empty($detail)) {
                $offer_detail->save(['detail' => $detail, 'money' => $offer_money]);
            } else {
                $offer_detail->delete();
            }

        }
    }
    public function array_do5($array1, $array2)
    {
        //$result = [];
        foreach ($array1 as &$item1) {
            foreach ($array2 as $item2) {
                if ($item1['type_id'] == $item2['type_id']) {
                    $item1['price'] = $item2['price']; // 更新price
                                                       //$result[] = $item1;
                }
            }
        }

        //unset($item1);
        return $array1;
    }
    public function array_dos($array)
    {
        $result = [];

        foreach ($array as $item) {
            $type_id = $item['type_id'];
            if (! isset($result[$type_id])) {
                $result[$type_id] = $item;
            } else {
                $result[$type_id]['num'] += $item['num'];
            }
        }

        $result = array_values($result);
        return $result;
    }
    public function export(Request $request, Send $model): void
    {
        $param = $request->param();
        $data  = $model->with(['user', 'school'])->scope('where', $param)->select();

        $header = ['学校', '供应商', '采购单号', '配送时间', '收货金额', '分类', '商品', '规格', '单位', '采购数量', '采购价格', '已收数量', '未收数量', '收货均价', '收货金额', '备注'];

        $body = [];
        foreach ($data as $item) {
            foreach ($item->detail as $key => $value) {
                $record              = [];
                $type                = Type::where('id', $value['type_id'])->find();
                $record['school']    = $item->school->name ?? '';
                $record['user']      = $item->user->nickname ?? '';
                $record['code']      = $item->code . ' ';
                $record['send_time'] = $item->send_time ?? '';
                $record['all_money'] = $item->money;
                $record['parent']    = Type::where('id', $type['parent_id'])->value('name') ?? '';
                $record['type']      = $type['name'] ?? '';
                $record['spec']      = Spec::where('id', $value['spec_id'])->value('name') ?? '';
                $record['brand']     = Brand::where('id', $value['brand_id'])->value('name') ?? '';
                $record['num']       = $value['num'] ?? '';
                $record['price']     = $value['price'] ?? '';
                $record['shou_num']  = $value['shou_num'] ?? '';
                $record['wei_num']   = $value['wei_num'] ?? '';
                $record['avg_price'] = $value['avg_price'] ?? '';
                $record['money']     = $value['money'] ?? '';
                $record['beizhu']    = $value['beizhu'] ?? '';
                $body[]              = $record;
            }
        }
        $this->exportData($header, $body, '采购单数据-' . date('YmdHis'));
    }
    public function array_do3($array1, $array2)
    {
        $mergedArray = [];

        // Create a map for the first array using type_id as key
        $array1Map = [];
        foreach ($array1 as $item) {
            $typeId             = $item['type_id'];
            $array1Map[$typeId] = $item;
        }

        // Merge arrays based on type_id and only keep the merged ones
        foreach ($array2 as $item) {
            $typeId = $item['type_id'];
            if (isset($array1Map[$typeId])) {
                $mergedArray[] = array_merge($array1Map[$typeId], $item);
            }
        }

        return $mergedArray;
    }
    public function array_do($array)
    {
        $result = [];

        foreach ($array as $item) {
            $type_id = $item['type_id'];
            if (! isset($result[$type_id])) {
                $result[$type_id] = $item;
            } else {
                $result[$type_id]['num'] += $item['num'];
                $result[$type_id]['money'] += $item['money'];
            }
        }

        $result = array_values($result);
        return $result;
    }
    public function array_do4($array1, $array2)
    {
        $assocArray1 = [];
        foreach ($array1 as $item) {
            $assocArray1[$item['type_id']] = $item;
        }

// Merge the arrays based on type_id
        $resultArray = [];
        foreach ($array2 as $item) {
            $type_id = $item['type_id'];
            if (isset($assocArray1[$type_id])) {
                $item['num'] = $assocArray1[$type_id]['num']; // Retain 'num' from first array
            }
            $resultArray[] = $item;
        }
        return $resultArray;
    }
    public function array_do2($data)
    {
        $groupedData = [];

        foreach ($data as $item) {
            $school_id = $item['school_id'];
            $type_id   = $item['type_id'];
            $key       = $school_id . '-' . $type_id;

            if (! isset($groupedData[$key])) {
                $groupedData[$key] = $item;
            }

            $groupedData[$key]['num'] += $item['num'];
        }
        $result = array_values($groupedData);
        return $result;
    }
    public function filterBySchoolId($array, $school_id)
    {
        return array_filter($array, function ($item) use ($school_id) {
            return $item['school_id'] == $school_id;
        });
    }
}
